1594. Закодированная сумма

 

Имеется набор строк, каждая из которых представляет собой натуральное число. Только вместо цифр строки содержат буквы от ‘A’ до ‘J’. Каждая буква обозначает одну цифру, а каждая цифра кодируется только одной буквой. Ни одно число не начинается нулем. В задаче требуется найти наибольшее возможное значение суммы всех чисел.

 

Вход. Состоит из нескольких тестов. Первая строка каждого теста содержит количество строк n (1 ≤ n ≤ 50).  Далее следуют n строк, содержащие буквы от ‘A’ до ‘J’.

 

Выход. Для каждого теста в отдельной строке вывести наибольшее возможное значение суммы всех чисел.

 

Пример входа

Пример выхода

2

ABC

BCA

1

ABCDEFGHIJ

1875

9876543210

 

 

РЕШЕНИЕ

жадный алгоритм

 

Анализ алгоритма

Элементы массива numbers содержат 10 допустимых букв: от ‘A’ до ‘J’. Запишем каждое число в десятичной системе счисления и просуммируем коэффициенты при одинаковых буквах. Например, для первого теста ABC = 100*A + 10*B + C, BCA = 100*B + 10*C + A. Сумма коэффициентов при букве ‘A’ равна 101, при ‘B’ – 110, при ‘C’ – 11. Массив m содержит эти данные в виде пар: <коэффициент, буква>.

Поскольку нам следует максимизировать полученную сумму, то букве с наибольшим коэффициентом должна соответствовать наибольшая цифра, то есть 9. Следующему по величине коэффициенту – цифра 8 и так далее. Сортируем элементы массива m по возрастанию коэффициентов. Единственная проблема – если в сумме задействованы все десять цифр (включая ноль), то не всякая буква может принимать значение 0, а только та, которая не встречается первой в словах. В массиве canzero отмечаем буквы, которые могут принимать нулевое значение: canzero[i] = 1, если буква ‘A’ + i может принимать значение 0.

В отсортированном по значениям коэффициентов массиве m ищем первую букву, которая может принимать нулевое значение и переставляем ее на нулевую позицию. Если в сумме задействовано менее 10 букв, но никакая буква нулевого значения принимать не будет. Сортируем ячейки массива m от первой до девятой.

После описанных процедур букве m[i].first приписываем значение i и вычисляем максимально возможное значение искомой суммы, равное

 

Реализация алгоритма

Объявим глобальные переменные.

 

vector<pair<long long,char> > m(10);

vector<string> numbers;

int canzero[10];

 

long long maximumSum(void)

{

  int i, j;

  long long pow10, s;

  for(i = 0; i < 10; i++)

    m[i].first = 0, m[i].second = i + 'A',canzero[i] = 1;

  for(i = 0; i < numbers.size(); i++)

  {

    pow10 = 1;

    for(j = numbers[i].size() - 1; j >= 0; j--)

    {

      m[numbers[i][j]-'A'].first += pow10;

      pow10 *= 10;

    }

    canzero[numbers[i][0]-'A'] = 0;

  }

  sort(m.begin(),m.end());

 

  for(i = 0; !canzero[m[i].second - 'A']; i++);

  swap(m[0],m[i]);

  sort(m.begin() + 1,m.end());

 

  for(s = i = 0; i < 10; i++)

    s += m[i].first * i;

  return s;

}

 

Основная часть программы.

 

while(scanf("%d\n",&n) == 1)

{

  numbers.clear();

  for(i = 0; i < n; i++)

    gets(s), numbers.push_back(s);

  res = maximumSum();

  printf("%lld\n",res);

}